Trojan source
実際に実行されるコードとエディタに表示されるコードを食い違わせる攻撃手法
https://trojansource.codes/
複数の攻撃手法がレポートされている
1. 文字の順序が入れ替わるunicode制御文字を使う
RTLを強制する制御文字を使っている
2. ゼロ幅スペース (U+200B)を差し込む
関数の呼び出し先が変わったり、条件式の結果が反転したりする
3. homoglyphを使う
見た目は同じだがcodepointが異なるアルファベット
これも関数の呼び出し先を変えたり、条件式の結果を反転させたりできる
原理的には全てのプログラム言語で実現可能
攻撃対象
if文や早期return、コメントアウト
unicode対応が完璧な近代的なテキストエディタと、プログラマの目
他人の書いたコードが入ってくるインフラ
pull requestやpatchなど
日本語ではトロイのソース?
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42574
しくみ
RTL制御文字を使っている
文字の順序が入れ替わる
U+202E
U+202E RTL override
‮ - Right-To-Left Override: U+202E - Unicode Character Table
https://gyazo.com/9d08dfc348e529861100426cb6f965fe
ブラウザのタイトルバーや本文も、この文字を解説しただけで影響を受けている
U+2066
U+2066 RTL Isolate
⁦ - Left-To-Right Isolate: U+2066 - Unicode Character Table
U+2069
U+2069 Pop directional isolate
⁩ - Pop Directional Isolate: U+2069 - Unicode Character Table
例:見た目に反してコメントアウトされているif文
https://github.com/nickboucher/trojan-source/blob/main/JavaScript/commenting-out.js
if文の部分はコメントアウトされていない様に見えるが、実際にはコメントアウトされている
VSCodeやemacsだとこんな感じ
https://gyazo.com/6aaa9271a6cacbce93c63614035b2e0e
正しくuncode対応していると、逆にこうなってしまう
Scrapboxでの対策
Trojan sourceに使われる文字を可視化した
code:commenting-out.js
#!/usr/bin/env node
var isAdmin = false;
/*‮ } ⁦if (isAdmin)⁩ ⁦ begin admins only */
console.log("You are an admin.");
/* end admins only ‮ { ⁦*/
例:if文が成立しそうで実はしない
https://github.com/nickboucher/trojan-source/blob/main/JavaScript/stretched-string.js
code:stretch-string.js
#!/usr/bin/env node
var accessLevel = "user";
if (accessLevel != "user‮ ⁦// Check if admin⁩ ⁦") {
console.log("You are an admin.");
}
例:ゼロ幅スペース (U+200B)が入っている
https://github.com/nickboucher/trojan-source/blob/main/JavaScript/invisible-function.js
code:invisible-function.js
#!/usr/bin/env node
function isAdmin() {
return false;
}
function is​Admin() {
return true;
}
if (is​Admin()) {
console.log("You are an admin\n");
} else {
console.log("You are NOT an admin.\n");
}
例:見た目は同じだがcodepointが違うアルファベット
こういうのをhomoglyphと呼ぶ様だshokai.icon
https://github.com/nickboucher/trojan-source/blob/main/JavaScript/homoglyph-function.js
code:homoglyph-function.js
#!/usr/bin/env node
function sayHello() {
console.log("Hello, World!\n");
}
function sayНello() {
console.log("Goodbye, World!\n");
}
sayНello();
HがU+41dになっている
https://gyazo.com/ba338ac11fa9bbeac4097d7988acca12
Н - Cyrillic Capital Letter En: U+041D - Unicode Character Table
対策
表示順序を制御する文字をそのまま描画しない
Githubはwarningを表示するようになった
https://nota.gyazo.com/ea4bcde503a46cd8d989cd538a20dcdb